package com.itheima.socket.tcp.demo14;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 就是使用线程池去处理我们多个客户端的请求
 */
public class ServerDemo01 {

    /**
     * 现在我们使用线程池将我们的服务器端代码进行了相关的改造，我们都知道线程池中线程是可以进行复用的，但是复用的前提：就是这个线程处理完毕了
     * 某一个任务，该线程才可以被复用。 这个线程处理任务的速度越快，那么这个线程复用性就越高，我们服务器端处理客户端的请求也就越多，服务器的
     * 性能也就越高；
     *
     * 现在我们的服务端的代码还是存在一些小的问题？
     *
     * while((len = inputStream.read(bytes)) != -1) {
     *     bufferedOutputStream.write(bytes , 0 , len);
     * }
     *
     *  问题的出现主要集中于上面的代码，上面的代码我们都知道这个read方法是一个阻塞方法，当我们的客户端完成了文件的上传，但是并没有通知
     *  服务端这个输出流已经关闭；那么此时我们这个while循环是结束不了，那么这个循环结束不了，那么我们这个线程能被我们线程池回收吗？
     *  不能被线程池进行回收，因此这个线程一直处于占用的状态；大家试想一下，如果我们现在线程池中的线程都是这样的状态，那么我们线程池
     *  还可以继续去处理其他的客户端吗? 就不可以了
     *
     *  总结：问题产生的主要原因是因为我们此时所使用的io模型中的read方法是阻塞式方法, 我们之前所使用的这种io模型我们将其称之为BIO
     *       传统的io模型;
     *
     *       如何再一次提高我们服务器的性能呢？  思路就是不使用BIO，那么使用啥呢？  ---> 使用新的io模型 NIO
     */

    public static void main(String[] args) throws IOException {

        // 创建一个线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);// 创建了一个具有10个线程线程池

        // 1. 创建ServerSocket对象
        ServerSocket serverSocket = new ServerSocket(8080) ;

        // 就是让我们的服务端不断的去监听客户端的请求
        while(true) {

            // 2. 监听客户端
            Socket socket = serverSocket.accept();

            // 向线程池中去提交任务
            executorService.submit(new ClientHandler(socket)) ;

        }

    }

}
